﻿using System;
using System.Threading.Tasks;
using Bit.Art.Api.Models;
using Bit.Art.Core;
using Bit.Art.Core.Extensions;
using Bit.Art.Core.Models;
using IdentityModel.Client;
using Microsoft.AspNetCore.Authentication;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
using NetMQ;
using NetMQ.Sockets;
using Serilog;

namespace Bit.Art.Api.Controllers
{
    /// <summary>
    /// 账户相关的API
    /// </summary>
    public class AccountController : Controller
    {
        private readonly SsoOption _option;
        private ILogger<AccountController> _logger;

        /// <summary>
        /// 
        /// </summary>
        /// <param name="optionsAccessor"></param>
        /// <param name="logger"></param>
        public AccountController(IOptions<ServerOptions> optionsAccessor, ILogger<AccountController> logger)
        {
            var options = optionsAccessor.Value;
            _option = options.SsoOption;
            _logger = logger;
        }

        /// <summary>
        /// 获取单个币种的存币信息
        /// </summary>
        /// <returns>存币地址和Tag相关信息</returns>
        [HttpGet]
        [Authorize(Policy = "account")]
        public Task<ApiCallResult<DepositInfo>> GetDepositAddress(string coin)
        {
            throw new NotImplementedException();
        }

        /// <summary>
        /// 提现
        /// </summary>
        /// <param name="coin">币种信息</param>
        /// <param name="amount">提现金额</param>
        /// <returns>提现申请id，以便后续查找。</returns>
        [HttpPost]
        [Authorize(Policy = "account")]
        public Task<ApiCallResult<string>> Withdraw(string coin, decimal amount)
        {
            throw new NotImplementedException();
        }

        /// <summary>
        /// 获取用户的信息
        /// </summary>
        [HttpGet]
        [Authorize(Policy = "profile")]
        public async Task<ApiCallResult<string>> UserInfo()
        {
            var ret = new ApiCallResult<string>();

            try
            {
                var userInfoClient = new UserInfoClient(string.Format($"{_option.ServerUrl}/connect/userinfo"));

                var token = await HttpContext.GetTokenAsync("access_token");
                var response = await userInfoClient.GetAsync(token);
                ret.Success = true;
                ret.Result = response.Raw;
            }
            catch (Exception e)
            {
                ret.Message = e.Message;
                Log.Logger.Error(e, "获取用户信息发生错误");
            }

            return ret;
        }

        /// <summary>
        /// 更新用户的信息.
        /// </summary>
        /// <param name="request">用户的信息更新。</param>
        [HttpPost]
        [Authorize(Policy = "profile")]
        public async Task<ApiCallResult<bool>> UpdateUserInfo([FromBody] UpdateAccountRequest request)
        {
            var result = new ApiCallResult<bool>();
            try
            {
                using (var client = new RequestSocket(Constants.SsoApiServerEndpoint))
                {
                    do
                    {
                        if (string.IsNullOrEmpty(request.Username))
                        {
                            result.Success = false;
                            result.ErrorCode = Constants.ErrorCodes.EMPTY_FIELD_VALUE;
                            result.Message = "Username";
                            break;
                        }

                        var msg = new AccountMessage()
                        {
                            Type = (int)AccountMessageType.UpdateProfile,
                            Username = request.Username,
                            Cellphone = request.Cellphone,
                            Avatar = request.Avatar,
                            Nickname = request.Nickname
                        };

                        client.SendFrame(msg.ToJson());
                        var response = await Task.Run(() =>
                        {
                            var res = client.ReceiveMultipartMessage();
                            var json = res.Last.ConvertToString(System.Text.Encoding.UTF8);
                            return Utility.From<ApiCallResult<ulong>>(json);
                        });
                        result.Success = response.Success;
                        result.Result = response.Result == 0L;
                        result.Message = response.Message;
                    } while (false);
                }
            }
            catch (Exception e)
            {
                result.Message = e.Message;
                Log.Logger.Error(e, "更新用户信息发生错误");
            }

            return result;
        }
    }
}